package com.oyjd.framework.ui.condsel;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Scroller;

/**
 * 滑动选择条件控件
 * 
 * @author 欧建东
 * @email oyjd@163.com
 * 
 */
public class CondSelect extends FrameLayout {
	/**
	 * 滑动控件
	 */
	private Scroller mScroller = null;
	/**
	 * 条件项容器
	 */
	protected LinearLayout cond;
	/**
	 * 指针容器1
	 */
	protected CondMask mask1;
	/**
	 * 指针容器2
	 */
	protected CondMask mask2;
	/**
	 * 控件总宽度
	 */
	private int allWidth;
	/**
	 * 指针宽度
	 */
	private float maskWidth;
	/**
	 * 条件项视图数据
	 */
	protected List<View> viewData = new ArrayList<View>();
	/**
	 * 监听器
	 */
	private List<OnCondListener> listeners = new ArrayList<OnCondListener>();

	/**
	 * 是否范围选择
	 */
	protected boolean areaFlag = false;

	/**
	 * 构造函数
	 * 
	 * @param context
	 */
	public CondSelect(Context context) {
		super(context);
		init(context);
	}

	/**
	 * 构造函数
	 * 
	 * @param context
	 * @param attrs
	 */
	public CondSelect(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(context);
	}

	/**
	 * 参数初始化
	 * 
	 * @param context
	 */
	private void init(Context context) {
		mScroller = new Scroller(context);
		//
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
		lp.gravity = Gravity.CENTER;
		cond = new LinearLayout(context);
		cond.setLayoutParams(lp);
		addView(cond);
		//
		mask1 = new CondMask(getContext());
		mask1.setBackgroundColor(Color.GRAY);
		mask2 = new CondMask(getContext());
		mask2.setBackgroundColor(Color.GRAY);
		mask2.setVisibility(View.GONE);
		mask2.setLook(mask1);
		addView(mask2);
		addView(mask1);
	}

	/**
	 * 滑动指针时迭代更新界面
	 */
	@Override
	public void computeScroll() {
		if (mScroller.computeScrollOffset()) {
			int x = mScroller.getCurrX();
			mask1.moveMask(x);
			mask2.moveMask(x);
			postInvalidate();
			if (mScroller.isFinished()) {
				mask1.status = CondMask.STATUS_STOP;
				mask2.status = CondMask.STATUS_STOP;
				//
				List<OnCondListener> tmpList = new ArrayList<OnCondListener>(listeners);
				for (OnCondListener listerner : tmpList) {
					if (null != listerner) {
						listerner.OnSelected(mask1.pos, areaFlag ? mask2.pos : mask1.pos);
					}
				}
			}
		}
	}

	/**
	 * 手势事件
	 */
	public boolean onTouchEvent(MotionEvent event) {
		super.onTouchEvent(event);

		float x = event.getX();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			// 如果屏幕的动画还没结束，你就按下了，我们就结束该动画
			if (mScroller != null) {
				if (!mScroller.isFinished()) {
					mScroller.abortAnimation();
				}
			}
			break;
		case MotionEvent.ACTION_MOVE:
			int px = (int) (x - maskWidth / 2);
			mask1.moveMask(px);
			mask2.moveMask(px);
			passPos(mask1);
			passPos(mask2);
			break;
		case MotionEvent.ACTION_UP:
		case MotionEvent.ACTION_CANCEL:
			moveDiff(mask1);
			moveDiff(mask2);
			break;
		}

		return true;
	}

	/**
	 * 快速移动经过特定位置
	 */
	private void passPos(CondMask mask) {
		if (CondMask.STATUS_STOP == mask.status) {
			return;
		}

		int cx = mask.getLeft();
		int p = 0;
		if (cx >= 0) {
			float n = Math.abs(cx % maskWidth);
			p = (int) (cx / maskWidth) + (n >= maskWidth / 2 ? 1 : 0);
			if (p > viewData.size() - 1) {
				p = viewData.size() - 1;
			}
		}
		mask.pos = p;

		//
		List<OnCondListener> tmpList = new ArrayList<OnCondListener>(listeners);
		for (OnCondListener listerner : tmpList) {
			if (null != listerner) {
				listerner.OnMoving(mask1.pos, areaFlag ? mask2.pos : mask1.pos);
			}
		}
	}

	/**
	 * 差位调整移动
	 */
	private void moveDiff(CondMask mask) {
		if (CondMask.STATUS_STOP == mask.status) {
			return;
		}

		int start = mask.getLeft();
		int selectPos;
		if (start < 0) {// 左边出界
			int end = 0;
			int dx = end - start;
			mScroller.startScroll(start, 0, dx, 0, Math.abs(dx) * 2);
			selectPos = 0;
		} else if (start > allWidth - maskWidth) {// 右边出界
			int end = (int) (allWidth - maskWidth);
			int dx = end - start;
			mScroller.startScroll(start, 0, dx, 0, Math.abs(dx) * 2);
			selectPos = viewData.size() - 1;
		} else {// 中间移动，以每项二分之一为界
			float n = start % maskWidth;
			int p = (int) (start / maskWidth);
			if (n >= maskWidth / 2) {
				selectPos = p + 1;
			} else {
				selectPos = p;
			}
			int end = (int) (selectPos * maskWidth);
			int dx = end - start;
			mScroller.startScroll(start, 0, dx, 0, Math.abs(dx) * 2);
		}
		mask.pos = selectPos;
		// 刷新界面
		invalidate();
	}

	/**
	 * 计算控件尺寸
	 */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		allWidth = MeasureSpec.getSize(widthMeasureSpec);
		int height = MeasureSpec.getSize(heightMeasureSpec);
		setMeasuredDimension(allWidth, height);
	}

	/**
	 * 设置各组件尺寸
	 */
	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);
		maskWidth = 1F * allWidth / viewData.size();
		mask1.layout((int) (mask1.pos * maskWidth), 0, (int) ((mask1.pos + 1) * maskWidth), this.getHeight());
		mask2.layout((int) (mask2.pos * maskWidth), 0, (int) ((mask2.pos + 1) * maskWidth), this.getHeight());
	}

	/**
	 * 设置子视图数据
	 * 
	 * @param data
	 *            视图数据
	 * @param defaultPos1
	 *            默认指针位置1
	 * @param defaultPos2
	 *            默认指针位置2
	 */
	public void setCondViews(List<View> data) {
		viewData = data;
		// 条件数据填充
		LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1);
		lp.gravity = Gravity.CENTER;

		cond.removeAllViews();
		for (View v : viewData) {
			v.setLayoutParams(lp);
			cond.addView(v);
		}
		// 指针设置
		maskWidth = 1F * allWidth / viewData.size();
		mask1.setLayoutParams(new LayoutParams((int) Math.ceil(maskWidth), LayoutParams.MATCH_PARENT));
		mask2.setLayoutParams(new LayoutParams((int) Math.ceil(maskWidth), LayoutParams.MATCH_PARENT));
		setCondPos(0, 0);
		// 刷新界面
		invalidate();
	}

	/**
	 * 设置指针位置
	 * 
	 * @param pos1
	 *            指针1位置
	 * @param pos2
	 *            指针2位置
	 */
	public void setCondPos(int pos1, int pos2) {
		mask1.pos = pos1;
		mask1.moveMaskDirect((int) (mask1.pos * maskWidth));
		mask2.pos = pos2;
		mask2.moveMaskDirect((int) (mask2.pos * maskWidth));
		//
		List<OnCondListener> tmpList = new ArrayList<OnCondListener>(listeners);
		for (OnCondListener listerner : tmpList) {
			if (null != listerner) {
				listerner.OnSelected(mask1.pos, areaFlag ? mask2.pos : mask1.pos);
			}
		}

	}

	/**
	 * 获取子视图数据
	 * 
	 * @return
	 */
	public List<View> getCondViews() {
		return viewData;
	}

	/**
	 * 添加条件选中监听器
	 * 
	 * @param listener
	 */
	public void setOnCondListener(OnCondListener listener) {
		if (null != listener) {
			listeners.add(listener);
		}
	}

	/**
	 * 删除条件选中监听器
	 * 
	 * @param listener
	 */
	public void removeOnCondListener(OnCondListener listener) {
		if (listeners.contains(listener)) {
			listeners.remove(listener);
		}
	}

	/**
	 * 设置是否可范围选择
	 */
	public void setAreaSelect(boolean flag) {
		areaFlag = flag;
		mask2.setVisibility(areaFlag ? View.VISIBLE : View.GONE);
	}

}
